<template>
  <div class="category-wrapper fixed w-full h-full left-0 top-0 z-10">
    <div class="absolute bg-white w-582px left-317px top-223px z-11 px-24px rounded-4px">
      <div class="pt-25px text-black text-18px font-medium leading-26px pb-24px">
        {{ isCombo ? categoryStore.comboName : categoryStore.name }}
      </div>
      <div class="max-h-240px overflow-scroll">
        <Combination v-if="isCombo === 0" :sku-list="categoryStore.skuList" @on-change="change" />
        <Combination
          v-for="(sku, index) in categoryStore.comboSkuList"
          v-else
          :key="index"
          :sku-list="sku"
          :spu-name="sku?.[0].name"
          @on-change="(actives) => change(actives, index)"
        />
      </div>
      <div class="absolute left-0 bottom-80px h-1px w-full category-line"></div>
      <div class="h-80px flex items-start category-footer">
        <div class="font-medium text-16px leading-23px category-total-wrod w-48px mt-32px">
          总计:
        </div>
        <div class="font-medium text-14px leading-20px category-total mt-34px w-14px">￥</div>
        <div class="mt-26px flex-1 flex">
          <div class="font-bold text-24px leading-29px category-total mr-8px">
            {{ isCombo ? categoryStore.getComboPrice : categoryStore.getPrice }}
          </div>
          <div
            v-if="
              (isCombo && categoryStore.getComboOriginPrice) ||
              (!isCombo && categoryStore.getOriginPrice)
            "
            class="line-through category-origin-total text-12px leading-17px mt-10px"
          >
            ￥{{ isCombo ? categoryStore.getComboOriginPrice : categoryStore.getOriginPrice }}
          </div>
        </div>
        <div
          v-if="selected === 'pending'"
          ref="addCartBtn"
          class="font-medium text-18px text-white w-186px h-48px text-center leading-48px rounded-48px category-add-button mt-16px cursor-pointer"
          @click="add"
        >
          添加至购物车
        </div>
        <div
          v-else-if="selected === 'disabled'"
          class="font-medium text-18px text-white w-186px h-48px text-center leading-48px rounded-48px bg-disable mt-16px cursor-not-allowed"
        >
          商品不可选
        </div>
        <div v-else class="mt-24px">
          <Calculate v-model="selected.number" :style="{ color: '#000' }" />
        </div>
      </div>
    </div>
    <div class="absolute left-931px top-223px cursor-pointer" @click="remove">
      <img :src="close" alt="" />
    </div>
    <Transition
      v-for="(item, index) in showMoveDot"
      :key="index"
      appear
      @before-appear="onBeforeAppear"
      @after-appear="onAfterAppear"
    >
      <div v-if="item" ref="addCart" class="w-40px h-40px fixed left-0 top-0 z-101">
        <img :src="dropImg" alt="" class="w-full h-full rounded-[50%] cart-icon" />
      </div>
    </Transition>
  </div>
</template>

<script lang="ts">
import close from '@renderer/assets/closeLogin.svg'
import { computed, defineComponent, onMounted, onUnmounted, PropType, ref } from 'vue'
import { CategoryGroup } from './type'
import Combination from './combination.vue'
import Calculate from '@renderer/components/calculate/index.vue'
import { useCategoryStore } from '@renderer/store/modules/category'
import { useCartStore } from '@renderer/store/modules/cart'
import { SKU } from '@renderer/store/modules/cart'
import { useUserStore } from '@renderer/store/modules/user'
export default defineComponent({
  name: 'Category',
  props: {
    sku: {
      type: Array as PropType<CategoryGroup[]>,
      default: () => []
    },
    isCombo: {
      type: Number,
      default: 0
    },
    comboId: {
      type: Number,
      required: false
    }
  },
  emits: ['on-close'],
  setup(props, { emit }) {
    const categoryStore = useCategoryStore()
    const cartStore = useCartStore()
    const userStore = useUserStore()
    const remove = () => emit('on-close')
    const addCart = ref<null | HTMLElement>(null)
    const addCartBtn = ref<null | HTMLElement>(null)
    const showMoveDot = ref<any>([])
    const elLeft = ref<number>(0)
    const elTop = ref<number>(0)
    const dropImg = ref<any>()
    const combination = computed(() => {
      const tmp = new Map()
      props.sku.forEach((s) => {
        const combi = s.combination
        combi.forEach((c) => {
          let value: Set<string> | null = null
          if (tmp.has(c.key)) {
            value = tmp.get(c.key)
          } else {
            value = new Set()
          }
          ;(value as Set<string>).add(c.value)
          tmp.set(c.key, value)
        })
      })
      return tmp
    })
    const name = computed(() => {
      return categoryStore.skuList?.[0]?.name
    })
    const change = (actives: any, index) => {
      const skuList = props.isCombo ? categoryStore.comboSkuList?.[index] : categoryStore.skuList
      const sku = skuList?.find((c) => {
        const combinations = JSON.parse(c.combination || '[]')?.map((v) => v.value) || []
        return JSON.stringify(combinations.sort()) === JSON.stringify([...actives].sort())
      })
      if (props.isCombo) {
        categoryStore.setSelectedComboSku(sku as SKU)
      } else {
        categoryStore.setSelectedSku(sku as SKU)
      }
    }
    const onBeforeAppear = (el) => {
      el.style.transform = `translate3d(${elLeft.value + 93}px,${elTop.value + 48}px , 0)`
      el.style.opacity = '0'
    }
    const listenInCart = () => {
      document.querySelector('.cartIcon')?.classList.add('moveToCart')
      setTimeout(() => {
        // 500毫秒后移除底部Tabbar购物车的DOM元素class
        document.querySelector('.cartIcon')?.classList.remove('moveToCart')
      }, 500)
    }
    const onAfterAppear = (el) => {
      // 获取底部购物车徽标
      const cartIconEl = document.querySelector('.cartIcon') as HTMLElement
      const badgePosition = cartIconEl.getBoundingClientRect()
      // 设置小球移动的位移
      el.style.transform = `translate3d(${badgePosition?.left + 30}px,${
        badgePosition?.top - 30
      }px,0)`
      // 增加贝塞尔曲线
      el.style.transition = 'transform .58s cubic-bezier(0.3, -0.25, 0.7, -0.15)'
      el.style.transition = 'transform .58s linear'
      showMoveDot.value = showMoveDot.value.map((_) => false)
      // 设置透明度
      el.style.opacity = '1'
      el.addEventListener('transitionend', () => {
        el.style.display = 'none'
        listenInCart()
      })
      // 监听小球动画结束方法
      el.addEventListener('webkitAnimationEnd', () => {
        console.log('2')
        el.style.display = 'none'
        listenInCart()
      })
    }
    const add = (e) => {
      showMoveDot.value = [...showMoveDot.value, true]
      const { left, top } = e.target.getBoundingClientRect()
      elLeft.value = left
      elTop.value = top
      if (props.isCombo) {
        dropImg.value = JSON.parse(categoryStore.combo?.imgs || '[]')?.[0]?.url
      } else {
        dropImg.value = categoryStore.spu?.imgs?.[0]?.url
      }
      if (!userStore.GetToken) {
        // 登录
        userStore.invokeLogin(true, () => {
          if (props.isCombo) {
            cartStore.addCombo({
              id: categoryStore.combo?.id,
              number: 1,
              skus: categoryStore.selectedComboSku,
              name: categoryStore.combo.name,
              video: categoryStore.combo.video,
              img: JSON.parse(categoryStore.combo.imgs || '[]').map((img) => img.url)
            })
          } else {
            cartStore.add(categoryStore.selectedSku)
          }
        })
      } else {
        if (props.isCombo) {
          cartStore.addCombo({
            id: categoryStore.combo?.id,
            number: 1,
            skus: categoryStore.selectedComboSku,
            name: categoryStore.combo.name,
            video: categoryStore.combo.video,
            img: JSON.parse(categoryStore.combo.imgs || '[]').map((img) => img.url)
          })
        } else {
          cartStore.add(categoryStore.selectedSku)
        }
      }
    }
    onMounted(() => {
      if (props.isCombo) {
        categoryStore.comboSku.forEach((comboSku) => {
          categoryStore.setSelectedComboSku(comboSku)
        })
      } else {
        categoryStore.setSelectedSku(categoryStore.sku)
      }
    })
    onUnmounted(() => {
      if (props.isCombo) {
        categoryStore.setSelectedComboSku(null)
      } else {
        categoryStore.setSelectedSku(null)
      }
    })
    const selected = computed(() => {
      if (props.isCombo) {
        if (!categoryStore.selectedComboSku || categoryStore.selectedComboSku.length < 1) {
          return 'disabled'
        }
        const selectedComboSkus = cartStore.getSelectedComboSkus
        const selectedComboSkuIds = categoryStore.selectedComboSku
          .map((sku) => sku.id)
          .sort()
          .join(',')
        const res = selectedComboSkus.find(
          (sku) => [...sku.skuIds].sort().join(',') === selectedComboSkuIds
        )
        return res || 'pending'
      }
      if (!categoryStore.selectedSku) {
        return 'disabled'
      }
      const selectedSkus = cartStore.getSelectedSkus
      const selectedSku = categoryStore.selectedSku
      const res = selectedSkus.find((s) => s.id === selectedSku.id)
      return res || 'pending'
    })
    return {
      close,
      add,
      remove,
      ...props,
      combination,
      Combination,
      change,
      categoryStore,
      name,
      addCart,
      selected,
      Calculate,
      cartStore,
      addCartBtn,
      onBeforeAppear,
      onAfterAppear,
      showMoveDot,
      dropImg
    }
  }
})
</script>

<style scoped>
.category-wrapper {
  background-color: rgba(0, 0, 0, 0.6);
}
.category-line {
  background-color: #bdbdbd;
}
.category-add-button {
  background-color: #4979ff;
}
.category-total-word {
  color: #333;
}
.category-total {
  color: #ff3c4e;
}
.category-origin-total {
  color: rgba(153, 153, 153, 0.6);
}
@keyframes mymove {
  0% {
    transform: scale(1);
  }
  25% {
    transform: scale(0.8);
  }
  50% {
    transform: scale(0.6);
  }
  75% {
    transform: scale(0.4);
  }
  100% {
    transform: scale(0.2);
  }
}
.cart-icon {
  animation: 0.88s mymove ease-in-out;
}
</style>
